/**
 * @author zhoukailiang
 * @implement 用相对位置来实现
 * @data 2012-05-19
 */
(function($) {
	// 是否有水平滚动条
	var hasXScroll;
	// 是否有垂直滚动条
	var hasYScroll;
	// 滚动条的宽度
	var scrollW;
	// 冻结行数
	var freezeRow;
	// 冻结列数
	var freezeCell;
	// 当前要冻结对象容器
	var freeze;
	var freezeTab;
	var recordTabTop;
	var rocordTabLeft;
	var timestamp;
	function freezeInit(event) {
		if (event) {
			freeze = event.data.freeze;
			freezeTab = event.data.freezeTab;
			timestamp = event.data.time;
			scrollW = event.data.scrollW;
		}

		var freezeoffset = freeze.offset();
		var freezeDom = freeze[0];

		// 通过判断容器的高是否一致 来确定是否有X轴上的滚动条
		hasYScroll = freezeTab[0].offsetHeight > freezeDom.offsetHeight;
		// 通过判断容器的宽
		hasXScroll = freezeTab[0].offsetWidth > freezeDom.offsetWidth;
		
		var freezeH = hasXScroll ? freezeDom.clientHeight : freezeDom.offsetHeight;
		var freezeW = hasYScroll ? freezeDom.clientWidth : freezeDom.offsetWidth;
		var tabW = freezeTab[0].offsetWidth;
		var tabH = freezeTab[0].offsetHeight;
		
		if(!hasXScroll && $("#xscroll" + timestamp)){
			$("#xscroll" + timestamp).remove();
		}
		
		if(!hasYScroll && $("#yscroll" + timestamp)){
			$("#yscroll" + timestamp).remove();
		}
		
		if (hasXScroll) {
			createScroll(freeze,timestamp,true);
		}
		if (hasYScroll) {
			createScroll(freeze,timestamp,false);
		}
		initContiner(event);
		if(event)
			event.stopPropagation();
	};
	function createScroll(freeze,timestamp,isX) {
		var _id ="freeze_";
		_id+= isX ? 'x':'y';
		_id +='scroll';
		if(freeze.find('[id^="'+_id+'"]').length  > 0) return;
		if($('#'+_id + timestamp)[0])
			return ;
		var _scroll = $("<div id='"+_id + timestamp + "'>");
		var _b = $("<div>");
		_scroll.append(_b);
		freeze.parent().append(_scroll);
		_scroll.bind('scroll', {
					time : timestamp,
					freeze : freeze
				}, scroll);
	}
	function scroll(event) {
		timestamp = event.data.time;
		if ($("#freeze_xscroll" + timestamp)) {
			var leftx = $("#freeze_xscroll" + timestamp).scrollLeft()
			$('#table_con'+timestamp).scrollLeft(leftx);
			$("#freeze_head" + timestamp).scrollLeft(leftx);
		}
		if ($("#freeze_yscroll" + timestamp)) {
			var topx = $("#freeze_yscroll" + timestamp).scrollTop()
			$('#table_con'+timestamp).scrollTop(topx);
			$("#freeze_left" + timestamp).scrollTop(topx);
		}
	}
	function initContiner(event) {
		if (event) {
			freeze = event.data.freeze;
			freezeTab = event.data.freezeTab;
			timestamp = event.data.time;
			recordTabTop = event.data.recordTabTop;
			rocordTabLeft = event.data.rocordTabLeft;
		}
		var ie = $.browser.msie;
		var offset = freeze.offset();
		var offsetTab = freezeTab.offset();
		var top = Math.round(offsetTab.top);//offsetTab.top;//
		var left = Math.round(offsetTab.left);//offsetTab.left;//
		var width = freeze.outerWidth(true);
		var height = freeze.outerHeight(true);
		// 需要计算的值
		// top层的宽高变量
		var topH = 0;
		var topW = 0;
		// 边框宽高变量
		var borderW = freezeTab[0].offsetWidth;
		var borderH = freezeTab[0].offsetHeight;
		var rows = freezeTab.find("tr");
		var cells = rows.find("th");

		var topRow = $("#freeze_top" + timestamp + ">table").eq(0).find('tr');
		var headRow = $("#freeze_head" + timestamp + ">table").eq(0).find('tr');
		var leftRow = $("#freeze_left" + timestamp + ">table").eq(0).find('tr');
		
		rows.each(function(index, ele) {
					var _eleH =  ie?$(ele).height():ele.clientHeight;//
					borderH -= _eleH;
					topRow.eq(index).height(_eleH);//.css({ height : _eleH });
					headRow.eq(index).height(_eleH);//.css({height : _eleH });
					leftRow.eq(index).height(_eleH);//.css({height : _eleH });
					$(ele).height(_eleH);//.css({ height : _eleH });
				});
		// 设置Head 行的列宽度
		var topCells = topRow.find('th');
		var headCells = headRow.find('th');
		var leftCells = leftRow.find('th');

		cells.each(function(index, elm) {
					var _elmW = ie?elm.clientWidth:$(elm).width() ;//
					borderW -=_elmW;
					var _elmOffset = $(elm).offset();
					topCells.eq(index).width(_elmW);//.css({ width : _elmW });
					headCells.eq(index).width(_elmW);//.css({ width : _elmW });
					leftCells.eq(index).width(_elmW);//.css({ width : _elmW });
					$(elm).width(_elmW);//.css({width : _elmW});
				});
				
				// 计算top层的高度
		for (var i = 0; i < freezeCell; i++)
			topW += $(cells[i]).outerWidth(true);
		for (var i = 0; i < freezeRow; i++)
			topH += $(rows[i]).outerHeight(true);
//		if($.browser.opera){
//			topW +=(borderW)*(freezeCell);
//		}
		
		if($.browser.msie ){
			borderW = (borderW /(cells.length+1));
			topW += borderW * 4;
			//topH += borderH;	
		}
		if($.browser.mozilla && borderH > 0){
			topW += borderH;
			topH += borderH;
		}
		
		
		var topTabH = topH;
		var headH = topH;
		var leftH = hasYScroll ? freeze[0].clientHeight : freezeTab[0].offsetHeight;//freezeTab.outerHeight(true);
		var headW =freeze[0].clientWidth;//freezeTab.outerWidth(true);
		
		if (hasXScroll && hasYScroll) {
			headW = freeze[0].offsetWidth - scrollW;
			leftH = freeze[0].offsetHeight - scrollW;
		} 
		// 设置Css样式
		var _offset = offset;//{top:top,left:left};//offsetTab;//
		$('#table_con'+timestamp).css('height',freeze[0].offsetHeight).css('overflow','auto').offset(offset);
		$("#freeze_head" + timestamp).css(getCss(headW, topH, 104)).offset(offset);
		$("#freeze_left" + timestamp).css(getCss(topW, leftH , 104)).offset(offset);
		$("#freeze_top" + timestamp).css(getCss(topW, topH, 105)).offset(offset)
		
		$("#freeze_xscroll" + timestamp).css({
						'overflow-x' : 'scroll',
						position : "relative",
						'z-index' : 105,
						'overflow-y' : 'hidden',
						'margin-top': -scrollW,
						'margin-left':rocordTabLeft,
						width : headW,
						height : scrollW 
					});
		$("#freeze_xscroll" + timestamp + " div").css({
						width : freezeTab[0].offsetWidth,
						height : scrollW ,
						filter : 'alpha(opacity=100)'
					});
		$("#freeze_yscroll" + timestamp).css({
						'overflow-y' : 'scroll',
						position : "relative",
						'z-index' : 105,
						'overflow-x' : 'hidden',
						'margin-top': -freeze[0].offsetHeight,
						'margin-left': freeze[0].clientWidth,
						height : leftH ,
						width : scrollW 
					})
		$("#freeze_yscroll" + timestamp + " div").css({
					height : freezeTab[0].offsetHeight ,
					width : scrollW ,
					filter : 'alpha(opacity=100)'
				});
		$("#freeze_head" + timestamp + ">table").css(getCss(freezeTab[0].offsetWidth, topTabH, 104));
		$("#freeze_left" + timestamp + ">table").css(getCss(topW, freezeTab[0].offsetHeight, 104));
		$("#freeze_top" + timestamp + ">table").css(getCss(topW, topTabH, 105));
		if(event)
			event.stopPropagation();
	}
	function getCss(width, height, zindex, left, top) {
		return {
			position : "relative",
			'background-color' : '#FFFFFF',
			overflow : 'hidden',
			opacity : '1',
			'margin-left': left,
			'margin-top': top ,
			width : width ,
			height : height ,
			'border-collapse':collapse,
			'z-index' : zindex
		};
	}
	function getTabContianers(tab, row, cell) {
		var contis = new Array();
		if (row == 0 && cell == 0) {
			return contis;
		}
		var rowCount = tab.find('tr').length;
		var cellCount = tab.find('tr>th').length;
		if(rowCount == 0 || cellCount == 0){
			return contis;
		}
		if(row > rowCount) row = rowCount;
		if(cell > cellCount) cell = cellCount;
		var tabClone = tab.clone();
		tabClone.attr("id", '');
		var headContainer = $("<div>");
		var topContianer = headContainer.clone();
		var leftContianer = headContainer.clone();

		topContianer.attr("id", 'freeze_top' + timestamp);
		headContainer.attr("id", 'freeze_head' + timestamp);
		leftContianer.attr("id", 'freeze_left' + timestamp);

		var headTab = tabClone.clone().empty();
		var topTab = headTab.clone();
		var leftTab = headTab.clone();
		
		var rows = tabClone.find("tr");
		for (var i = 0; i < rows.length; i++) {
			var currRow = rows.eq(i);
			if (i < row) {
				headTab.append(currRow);
			}
			if (cell > 0) {
				var currLeftRow = currRow.clone().empty();
				var currCells = currRow.clone().children();
				for (var j = 0; j < cell; j++) {
					currLeftRow.append($(currCells[j]));
				}
				leftTab.append(currLeftRow);
			}
			if (cell > 0 && row > i) {
				var currTopRow = currRow.clone();
				var currCells = currTopRow.children();
				for (var j = cell; j < currCells.length; j++) {
					$(currCells[j]).remove();
				}
				topTab.append(currTopRow);
			}
		}

		topContianer.append(topTab);
		headContainer.append(headTab);
		leftContianer.append(leftTab);
		if (row > 0 && cell > 0) {
			contis[0] = headContainer;
			contis[1] = leftContianer;
			contis[2] = topContianer;
			return contis;
		}
		if (row > 0) {
			contis[0] = headContainer;
		}
		if (cell > 0) {
			contis[0] = leftContianer;
		}
		return contis;
	}
	jQuery.fn.freeze = function(row, cell) {
		timestamp = new Date().getTime();
		freezeTab = $(this);
		//freeze = $(this).parent();
		if (freezeTab.length == 0) {
			return;
		}
		var _freeze = freezeTab.parent();
		scrollW = _freeze[0].offsetWidth - _freeze[0].clientWidth
		if (scrollW == 0) {
			scrollW = _freeze[0].offsetHeight - _freeze[0].clientHeight;
		}
		//兼容FireFox容器刚好滚动条的宽度不显示问题
		if(($.browser.mozilla) && scrollW > 5){
			scrollW +=0.5;
		}
		
		_freeze.css('overflow','hidden').css('position','relative');
		//初始化最外层的容器Div
		freeze = $("<div id='"+timestamp+"'>")
		freeze.width(_freeze.width());
		freeze.height(_freeze.height());
		freeze.css('width','100%').css('overflow','hidden').css('position','relative');
		var _table_con = freeze.clone();
		
		_table_con.attr('id','table_con'+timestamp).css('z-index',100).css('width','100%').css('overflow','auto');
		_table_con.append(freezeTab);
		freeze.prependTo(_freeze);
		freeze.append(_table_con);
		
		recordTop =	freezeTab.css('margin-top');
		rocordLeft = freezeTab.css('margin-top');
		freezeRow = row;
		freezeCell = cell;
		var data = {
				time : timestamp,
				freeze : _table_con,
				scrollW : scrollW,
				freezeTab : freezeTab,
				recordTabTop : recordTabTop,
				rocordTabLeft : rocordTabLeft
		};
		_freeze.find('[id^="freeze"]').each(function(){$(this).remove()});
		$(getTabContianers(freezeTab, row, cell)).each(function() {
					freeze.append(this)
					$(this).bind("resize", data, freezeInit);
				});
		freezeInit();
		//_table_con.bind("scroll", data, scroll);
		_freeze.bind('resize',freezeInit);
		//$(document).bind('resize',freezeInit);
		$(window).bind("resize", data, freezeInit);
	}
})(jQuery);
